home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- ShapesDemo
- Example submitted by by David Clegg
-
- This unit contains the base Shape class and its descendants, which are used
- to render onto a GDI+ drawing surface.
- *******************************************************************************/
-
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
-
- namespace ShapesDemo
- {
- /// <summary>
- /// Base class for all shapes to descend from. It implements the logic for
- /// drawing an outline of the shape, and for filling the shape using the
- /// specified brush. It implements the IDisposable interface as the canvas
- /// reference needs to be disposed
- /// Concrete classes need only implement the GetShape method which should
- /// return a GraphicsPath instance representing the bounds of the shape.
- /// As a contrast, some concrete classes may also implement alternative
- /// methods for drawing the outline and filling the shape.
- /// </summary>
- public abstract class Shape : IDisposable {
- private Point fOldStartPoint;
- private Point fOldEndPoint;
- private Graphics fCanvas;
- private bool fDisposed = false;
-
- protected Graphics Canvas {
- get {return fCanvas;}
- }
-
- public Shape(Graphics canvas)
- {
- fCanvas = canvas;
- }
-
- /// <summary>
- /// Implement IDisposable.Dispose to ensure the fCanvas Graphics reference
- /// is explicitly disposed.
- /// </summary>
- public void Dispose() {
- if (!fDisposed) {
- fCanvas.Dispose();
- fDisposed = true;
- }
- }
-
- /// <summary>
- /// Destructor. Used to call .Dispose to ensure that fCanvas.Dispose
- /// is called if it hasn't already been done.
- /// </summary>
- ~Shape() {
- Dispose();
- }
-
- /// <summary>
- /// Draws a solid shape based on the startPoint and endPoint
- /// co-ordinates. Concrete classes must implement the GetShape method
- /// to determine the bounds for the shape.
- /// </summary>
- public void Draw(Point startPoint, Point endPoint, Brush brush) {
- //Draw the shape
- fCanvas.FillRegion(brush, new Region(GetShape(startPoint, endPoint)));
-
- //As the outline has a size of 1, it will still be visible along
- //some points of the shape. Draw another outline which uses a pen
- //the same color as the fill if it uses a SolidBrush, or one that
- //uses the same color as the original outline for other brush types.
- if (brush is SolidBrush)
- DoOutline(new Pen(((SolidBrush)brush).Color, 1), startPoint, endPoint);
- else
- DoOutline(new Pen(Color.Black, 1), startPoint, endPoint);
- }
-
- /// <summary>
- /// Draws an outline of a shape based in the startPoint and endPoint
- /// co-ordinates. Concrete classes must implement the GetShape method
- /// to determine the bounds for the shape.
- /// </summary>
- public void DrawOutline(Point startPoint, Point endPoint) {
- //First erase the last Outline
- Pen lPen = new Pen(Color.White, 1);
- DoOutline(lPen, fOldStartPoint, fOldEndPoint);
-
- //Draw the new Outline
- lPen = new Pen(Color.Black, 1);
- DoOutline(lPen, startPoint, endPoint);
-
- //Save the start and end points for next time
- fOldStartPoint = startPoint;
- fOldEndPoint = endPoint;
- }
-
- /// <summary>
- /// Return a Rectangle structure to represent the bounds of the shape.
- /// </summary>
- protected System.Drawing.Rectangle GetRectangle(Point startPoint, Point endPoint) {
- return System.Drawing.Rectangle.FromLTRB(startPoint.X, startPoint.Y,
- endPoint.X, endPoint.Y);
- }
-
- /// <summary>
- /// Draws the outline for the shape.
- /// </summary>
- private void DoOutline(Pen pen, Point startPoint, Point endPoint) {
- GraphicsPath lGraphicsPath = GetShape(startPoint, endPoint);
- fCanvas.DrawPath(pen, lGraphicsPath);
- }
-
- protected abstract GraphicsPath GetShape(Point startPoint, Point endPoint);
- }
-
- /// <summary>
- /// Class to draw a rectangle.
- /// </summary>
- public class Rectangle : Shape {
- public Rectangle(Graphics canvas) : base (canvas) {}
-
- /// <summary>
- /// Alternative method to draw a solid rectangle. Not as good as the
- /// inherited Draw method as it doesn't cater for if an endPoint X or Y
- /// value is less than its corresponding startPoint value.
- /// </summary>
- public void DrawRectangle(Brush brush, Point startPoint, Point endPoint) {
- Canvas.FillRectangle(brush, GetRectangle(startPoint, endPoint));
- }
-
- /// <summary>
- /// Alternative method to draw a rectangle outline. Not as good as the
- /// inherited Draw method as it doesn't cater for if an endPoint X or Y
- /// value is less than its corresponding startPoint value.
- /// </summary>
- public void OutlineRectangle(Pen pen, Point startPoint, Point endPoint) {
- Canvas.DrawRectangle(pen, GetRectangle(startPoint, endPoint));
- }
-
- protected override GraphicsPath GetShape(Point startPoint, Point endPoint) {
- GraphicsPath lRetVal = new GraphicsPath();
-
- Point lTopRight = new Point(startPoint.X, endPoint.Y);
- Point lBottomLeft = new Point(endPoint.X, startPoint.Y);
-
- lRetVal.AddLine(startPoint, lTopRight);
- lRetVal.AddLine(lTopRight, endPoint);
- lRetVal.AddLine(endPoint, lBottomLeft);
- lRetVal.AddLine(lBottomLeft, startPoint);
- return lRetVal;
- }
- }
-
- /// <summary>
- /// Class to draw an ellipse.
- /// </summary>
- public class Ellipse: Shape {
- public Ellipse(Graphics canvas) : base (canvas){}
-
- protected override GraphicsPath GetShape(Point startPoint, Point endPoint) {
- GraphicsPath lRetVal = new GraphicsPath();
- lRetVal.AddEllipse(GetRectangle(startPoint, endPoint));
- return lRetVal;
- }
-
- public void DrawEllipse(Brush brush, Point startPoint, Point endPoint) {
- Canvas.FillEllipse(brush, GetRectangle(startPoint, endPoint));
- }
-
- /// <summary>
- /// Alternative method to draw an Elipse outline. Not as good as the
- /// inherited Draw method as it doesn't cater for if an endPoint X or Y
- /// value is less than its corresponding startPoint value.
- /// </summary>
- public void OutlineEllipse(Pen pen, Point startPoint, Point endPoint) {
- Canvas.DrawEllipse(pen, GetRectangle(startPoint, endPoint));
- }
- }
-
- /// <summary>
- /// Class to draw a triangle.
- /// </summary>
- public class Triangle: Shape {
- public Triangle(Graphics canvas) : base (canvas){}
-
- /// <summary>
- /// Create a GraphicsPath object representing the bounds for the triangle
- /// </summary>
- protected override GraphicsPath GetShape(Point startPoint, Point endPoint) {
- GraphicsPath lRetVal = new GraphicsPath();
-
- Point lStartPoint = new Point(endPoint.X - ((endPoint.X - startPoint.X) / 2), startPoint.Y);
- Point lBottomLeft = new Point(startPoint.X, endPoint.Y);
-
- lRetVal.AddLine(lStartPoint, endPoint);
- lRetVal.AddLine(endPoint, lBottomLeft);
- lRetVal.AddLine(lBottomLeft, lStartPoint);
- return lRetVal;
- }
- }
-
- /// <summary>
- /// Class to draw a Line.
- /// </summary>
- public class Line: Shape {
- public Line(Graphics canvas) : base (canvas){}
-
- /// <summary>
- /// Create a GraphicsPath object representing the bounds for the Line
- /// </summary>
- protected override GraphicsPath GetShape(Point startPoint, Point endPoint) {
- GraphicsPath lRetVal = new GraphicsPath();
- lRetVal.AddLine(startPoint, endPoint);
- return lRetVal;
- }
-
- public void DrawLine(Pen pen, Point startPoint, Point endPoint) {
- Canvas.DrawLine(pen, startPoint, endPoint);
- }
- }
-
-
- }
-